import csv
from decimal import Decimal

from django.core.management.base import BaseCommand
from django.core.files.uploadedfile import InMemoryUploadedFile

from oscar.apps.catalogue.models import Product, Category, ProductAttribute,\
                                        ProductClass, ProductCategory,\
                                        ProductAttributeValue
from oscar.apps.partner.models import Partner, StockRecord

class Command(BaseCommand):

    def handle(self, *args, **options):
        self.set_initial_data()

        # Start processing CSV
        if isinstance(args[0], InMemoryUploadedFile):
            csv_reader = csv.reader(args[0], delimiter=',')
        else:
            f = open(args[0], 'rb')
            csv_reader = csv.reader(f, delimiter=',')

        first = True
        for row in csv_reader:
            if first:
                first = False
                continue

            if not row: continue

            print row

            sku = row[0]
            title = row[1]
            category = row[2]
            color = row[3]
            talle = row[4]
            peso = row[5]
            price = row[6]
            stock = row[7]

            category = self.init_or_get_category(category)

            canonical_product = self.get_or_create_canonical_product(title=title,
                                                                color=color,
                                                                category=category)
            if canonical_product is None:
                continue

            p_var = Product.objects.filter(upc=sku)
            if p_var.exists():
                continue

            p_var = Product()
            p_var.parent = canonical_product
            p_var.title = title + ' ' + talle
            p_var.upc = sku
            #p_var.title = title
            p_var.product_class = self.product_class
            p_var.save()

            #Set talle attribute
            talle_attr = ProductAttributeValue()
            talle_attr.product = p_var
            talle_attr.attribute = self.pa_talle
            talle_attr.value_text = talle
            talle_attr.save()

            # Associate peso
            peso_attr = ProductAttributeValue()
            peso_attr.product = p_var
            peso_attr.attribute = self.pa_peso
            peso_attr.value_text = peso
            peso_attr.save()

            # Set the price
            rec = StockRecord()
            rec.product = p_var
            rec.partner = self.partner
            rec.partner_sku = sku
            rec.price_excl_tax = Decimal(price)
            rec.num_in_stock = int(stock)
            rec.save()

    def set_initial_data(self):
        partner = Partner.objects.filter(name='MATRISAMOR')
        if partner.exists():
            self.partner = partner[0]
        else:
            self.partner = Partner()
            self.partner.name = 'MATRISAMOR'
            self.partner.save()

        product_class = ProductClass.objects.filter(name='zapato')
        if product_class.exists():
            self.product_class = product_class[0]
        else:
            self.product_class = ProductClass()
            self.product_class.name = 'zapato'
            self.product_class.track_stock = False
            self.product_class.save()

        pa_peso = ProductAttribute.objects.filter(name='peso')
        if pa_peso.exists():
            self.pa_peso= pa_peso[0]
        else:
            self.pa_peso = ProductAttribute()
            self.pa_peso.name = 'peso'
            self.pa_peso.save()

        pa_talle = ProductAttribute.objects.filter(name='talle')
        if pa_talle.exists():
            self.pa_talle = pa_talle[0]
        else:
            self.pa_talle = ProductAttribute()
            self.pa_talle.name = 'talle'
            self.pa_talle.save()

        pa_color = ProductAttribute.objects.filter(name='color')
        if pa_color.exists():
            self.pa_color = pa_color[0]
        else:
            self.pa_color = ProductAttribute()
            self.pa_color.name = 'color'
            self.pa_color.save()

        self.categories = {
            'BE': 'Beans',
            'BI': 'Baking ingredients',
            'CE': 'Cereals',
            # etc
        }


    def init_or_get_category(self, cat_name):
        """Loads existing category from DB or creates a new one"""

        if Category.objects.filter(name=cat_name).exists():
            category = Category.objects.get(name=cat_name)
        else:
            #category = root_category.add_child(name=cat_name)
            category = Category.add_root(name=cat_name)

        return category


    def get_or_create_canonical_product(self, title, color, category):


        product = Product.objects.filter(title=title).filter(upc__isnull=True)
        if not product.exists():
            product = Product()

            product.title = title

            product.product_class = self.product_class
            product.save()

            # Associate with a category
            cat_prod = ProductCategory()
            cat_prod.product = product
            cat_prod.category = category
            cat_prod.is_canonical = True
            cat_prod.save()

            # Associate color
            attr_value = ProductAttributeValue()
            attr_value.product = product
            attr_value.attribute = self.pa_color
            attr_value.value_text = color
            attr_value.save()

        else:
            product = product[0]

        return product


